package model

import (
	"fmt"
	"github.com/go-gin-admin/global"
	"github.com/go-gin-admin/util"
	"github.com/jinzhu/gorm"
)

type IDept interface {
	InsertDept() (int64, error)        // 增加部门
	GetDeptTree() (interface{}, error) // 获取部门树
	RemoveDept(deptId int64) error     // 删除部门
	UpdateDept() error                 // 修改部门
}

// 部门
type Dept struct {
	DeptId   int64  `json:"deptId" gorm:"primary_key"`  // 部门id
	DeptName string `json:"deptName"`                   // 部门名称
	Sort     int64  `json:"sort"`                       // 排序
	ParentId int64  `json:"parentId"`                   // 父级id
	DeptPath string `json:"deptPath"`                   // 层级id
	DelFlag  string `json:"delFlag" gorm:"default:'0'"` // 删除标记,1:已删除,0:正常
	BaseModel

	Children []*Dept `json:"children"` // 子节点，忽略字段
}

// 增加部门
func (d *Dept) InsertDept() (int64, error) {

	result := global.GDB.Table("sys_dept").Create(&d)
	if result.Error != nil {
		err := result.Error
		return 0, err
	}
	row, err := getRow(d.ParentId, "0")
	if err != nil {
		return 0, err
	}
	deptPath := ""
	// 如果获取的deptId为0，说明没有找到当前行的数据,为顶级的数据
	if row.DeptId == 0 {
		// 更新新插入的数据的dept_path
		deptPath += "/0" + "/" + util.IntToString(d.DeptId)
	} else {
		deptPath = row.DeptPath + "/" + util.IntToString(d.DeptId)
	}
	// 更新新建的文件的deptPath字段
	if err = setDeptPath(deptPath, d.DeptId); err != nil {
		fmt.Println("插入失败")
		return 0, err
	}
	return d.DeptId, nil
}

// 获取部门tree
func (d *Dept) GetDeptTree() (interface{}, error) {
	// 获取部门列表
	deptList, err := getDeptList()
	if err != nil {
		return nil, err
	}
	// 将部门列表转换成tree返回
	tree, _ := listConvertTree(deptList)
	return tree, nil
}

// 删除部门
func (d *Dept) RemoveDept(deptId int64) error {
	// 获取当前删除的信息
	row, _ := getRow(deptId, "0")
	table := global.GDB.Table("sys_dept")
	table = table.Where("dept_path LIKE ?", row.DeptPath+"%")
	if err := table.Update("del_flag", "1").Error; err != nil {
		return err
	}
	return nil
}

// 更新部门
func (d *Dept) UpdateDept() error {
	table := global.GDB.Table("sys_dept")
	table = table.Where("dept_id = ?", d.DeptId)
	if err := table.Updates(map[string]interface{}{"dept_name": d.DeptName, "sort": d.Sort, "update_time": d.UpdateTime}).Error; err != nil {
		return err
	}
	return nil
}

// 获取当前行
func getRow(id int64, state string) (Dept, error) {
	var dept Dept
	table := global.GDB.Table("sys_dept").Select("dept_id, dept_name, sort, create_time, update_time, parent_id, dept_path, del_flag")
	table = table.Where("del_flag = ?", state)
	table = table.Where("dept_id = ?", id)
	if err := table.First(&dept).Error; err != nil {
		// 判断错误
		switch {
		case err == gorm.ErrRecordNotFound:
			// 说明没有找到
			return dept, nil
		case err != nil:
			return dept, err
		}
	}
	return dept, nil
}

// 设置部门的deptPath字段
func setDeptPath(deptPath string, deptId int64) error {
	table := global.GDB.Table("sys_dept")
	table = table.Where("dept_id = ?", deptId)
	if err := table.Update("dept_path", deptPath).Error; err != nil {
		return err
	}
	return nil
}

// 获取所有的部门列表
func getDeptList() ([]Dept, error) {
	var deptList []Dept
	// 拼接查询语句
	table := global.GDB.Table("sys_dept").Select("dept_id, dept_name, sort, create_time, update_time, parent_id, dept_path, del_flag")
	table = table.Where("del_flag = '0'").Order("sort desc")
	if err := table.Find(&deptList).Error; err != nil {
		return nil, err
	}
	return deptList, nil
}

func listConvertTree(dept []Dept) (interface{}, error) {
	depts := make([]*Dept, 0)
	for i := 0; i < len(dept); i++ {
		// 如果当前部门的parentId为0，说明是顶级，直接加入到depts
		if dept[i].ParentId == 0 {
			depts = append(depts, &dept[i])
		}
		for j := 0; j < len(dept); j++ {
			// 如果当前节点的parentId等于等于第一层节点的id，说明是下一层级的节点
			if dept[j].ParentId == dept[i].DeptId {
				if dept[i].Children == nil {
					dept[i].Children = make([]*Dept, 0)
				}
				dept[i].Children = append(dept[i].Children, &dept[j])
			} else {
				if dept[i].Children == nil {
					dept[i].Children = make([]*Dept, 0)
				}
			}
		}
	}
	// 获取所有
	return depts, nil
}
